#include <iostream>


//RTTI运行时类型识别
//RTTI 运行时类型识别，。。。。动态绑定

/**
 * 
 * 
 * 
 * 
 * 1.通过运行时类型识别，程序能够与使用基类的指针或者引用来检测这些指针或者引用所指向对象的
 * 实际派生类型
 * （1）dynamic_cast运算符：能够将基类的指针胡总二号引用安全的转换成派生类的指针胡总和引用
 * （2）typeid运算符：返回指针或者所指定对象的实际类型
 * 补充：
 *  RTTI要想正常工作，基类中至少需要一个虚函数，不然两个运算符得出的结果可能和预料的不一样
 * 只有虚函数的存在，这两个运算符才会使用指针或者引用绑定的对象的动态类型。
 * 
 * 2.dynamic_cast
 *  Men*men=dynamic_cast<Men*>(phuman);
 * 
 * 3.typeid运算符
 * 作用：
 *  主要判断两个指针指向的类型是都相同
 * typeid(类型/引用)
 * 拿到对象类型信息，typeid就会返回一个常量对象的引用，type_info
 * 
 * 
 * 
 * 
*/


class Human{
    public:
        Human(){}
        virtual void run(){
            std::cout<<"human run"<<std::endl;
        }
};

class Men:public Human
{
public:
    Men(){}
    void run(){
        std::cout<<"men run"<<std::endl;
    }

};





int main(){

    Human*phuman=new Men;

    // phuman->run();
    // delete phuman;
    
    Men*men=dynamic_cast<Men*>(phuman);
    //const type_info &tp=typeid(*phuman);
    if(men!=NULL){
        men->run();

        std::cout<<typeid(*men).name()<<std::endl;
    }

       


}


//虚函数表
//c++11中，如果类中含有虚函数，百年一起就对该类产生一个虚函数表
//虚函数表中有很多项，每一项都是一个指针，每个指针指向这个雷利各个虚函数的入口地址
//虚函数表里第一个表很特殊，它指向的不是虚函数的入口地址，它指向的是
//与这类相关联的type_info对象

/**
 * Human*phuman=new Men;
 * const type_info&tp=typeid(*phuman);
 * 
 * 
*/
//如phuman指向的是我们看不见的指针，这个指针指向水，指向的就是这个对象所在类Men里的虚函数表